from typing import Final, Dict, List
from enum import Enum, unique

# ===================== 基础配置 =====================
# 项目名称
PROJECT_NAME: Final[str] = "Multi-Agent Entertainment Search System"
# 项目版本
PROJECT_VERSION: Final[str] = "v1.0.0"
# 编码格式
DEFAULT_CHARSET: Final[str] = "utf-8"
# 时间格式（全局统一，适配任务调度Agent）
DEFAULT_DATETIME_FORMAT: Final[str] = "%Y-%m-%d %H:%M:%S"

# ===================== Redis配置（核心，必须匹配本地Redis） =====================
# Redis地址（本地默认localhost，远程填服务器IP）
REDIS_HOST: Final[str] = "localhost"
# Redis端口（默认6379）
REDIS_PORT: Final[int] = 6379
# Redis数据库编号（默认0，可自定义）
REDIS_DB: Final[int] = 0
# Redis密码（本地无密码则留空，远程Redis填实际密码）
REDIS_PASSWORD: Final[str] = ""
# Redis连接池大小（根据并发量调整，默认20）
REDIS_POOL_SIZE: Final[int] = 20
# 分布式锁配置
REDIS_LOCK_TIMEOUT: Final[int] = 5  # 锁超时时间（秒），避免死锁
REDIS_LOCK_RETRIES: Final[int] = 3  # 锁获取重试次数
REDIS_LOCK_RETRY_DELAY: Final[float] = 0.1  # 锁重试间隔（秒）
# Redis操作重试配置
REDIS_RETRY_ATTEMPTS: Final[int] = 3  # 网络抖动时重试次数
REDIS_RETRY_WAIT_SECONDS: Final[int] = 1  # 重试最小等待时间（秒）

# ===================== Nacos配置（匹配本地/服务器Nacos） =====================
# Nacos地址（默认本地8848端口，集群填多个地址用逗号分隔）
NACOS_SERVER_ADDRESSES: Final[str] = "localhost:8848"
# Nacos命名空间（建议创建专属命名空间，填ID或名称）
NACOS_NAMESPACE: Final[str] = "entertainment-multi-agent"
# Nacos用户名（默认nacos）
NACOS_USERNAME: Final[str] = "nacos"
# Nacos密码（默认nacos）
NACOS_PASSWORD: Final[str] = "nacos"
# 配置中心相关（MCP跨集群同步）
NACOS_CONFIG_GROUP: Final[str] = "DEFAULT_GROUP"  # 配置分组
NACOS_CONFIG_DATA_ID: Final[str] = "maess_config"  # 配置数据ID
NACOS_CONFIG_REFRESH_INTERVAL: Final[int] = 5  # 配置刷新间隔（秒）

# ===================== Milvus配置 =====================
# Milvus地址（本地默认localhost）
MILVUS_HOST: Final[str] = "localhost"
# Milvus端口（默认19530）
MILVUS_PORT: Final[int] = 19530
# Milvus数据库名称（默认default）
MILVUS_DB_NAME: Final[str] = "default"
# Milvus集合名称（娱乐领域向量集合）
MILVUS_COLLECTION_NAME: Final[str] = "entertainment_vector"
# 向量维度（CLIP模型默认512维，根据实际模型调整）
MILVUS_VECTOR_DIM: Final[int] = 512

# ===================== MinIO配置 =====================
# MinIO地址（本地默认localhost:9000）
MINIO_ENDPOINT: Final[str] = "localhost:9000"
# MinIO访问密钥
MINIO_ACCESS_KEY: Final[str] = "minioadmin"
# MinIO秘密密钥
MINIO_SECRET_KEY: Final[str] = "minioadmin"
# MinIO桶名称（存储多模态数据）
MINIO_BUCKET_NAME: Final[str] = "maess-multimodal"
# MinIO是否启用HTTPS（本地默认False）
MINIO_SECURE: Final[bool] = False

# ===================== 系统常量 =====================
# 缓存过期时间（通用，秒）
CACHE_EXPIRE_DEFAULT: Final[int] = 3600  # 1小时
CACHE_EXPIRE_HOT_KEY: Final[int] = 86400  # 热key缓存24小时
CACHE_EXPIRE_TASK_STATE: Final[int] = 3600  # TaskState保留1小时
CACHE_EXPIRE_AGENT_STATE: Final[int] = 1800  # Agent状态缓存30分钟
CACHE_EXPIRE_GLOBAL_STATE: Final[int] = 360  # 全局状态缓存6分钟

# 限流阈值（原有基础上补充DEFAULT_RATE_LIMIT字典，适配限流Agent）
RATE_LIMIT_GLOBAL: Final[int] = 1000  # 全局限流：1000次/分钟
RATE_LIMIT_USER: Final[int] = 60  # 用户级限流：60次/分钟
RATE_LIMIT_HOT_KEY: Final[int] = 1000  # 热key限流：1000次/秒
# 热key阈值（1秒内查询次数超过此值则标记为热key）
HOT_KEY_THRESHOLD: Final[int] = 1000
# Agent并发数限制（单实例最大并发任务数）
AGENT_MAX_CONCURRENT: Final[int] = 50
# Agent调用超时时间（秒）
AGENT_CALL_TIMEOUT: Final[int] = 10
# 任务状态更新频道
TASK_STATE_UPDATE_CHANNEL: Final[str] = "task:state:update"

# ===================== 任务调度相关常量（适配任务调度Agent） =====================
# 任务状态字典
TASK_STATUSES = {
    'PENDING': 'pending',
    'RUNNING': 'running',
    'COMPLETED': 'completed',
    'FAILED': 'failed',
    'CANCELLED': 'cancelled',
    'RETRYING': 'retrying'
}

# 任务状态枚举类
class TaskStatusConst:
    PENDING = 'pending'
    RUNNING = 'running'
    COMPLETED = 'completed'
    FAILED = 'failed'
    CANCELLED = 'cancelled'
    RETRYING = 'retrying'

# 任务优先级枚举类
class TaskPriority:
    LOW = 0
    NORMAL = 5
    HIGH = 8
    URGENT = 10

# ===================== 缺失依赖补充（关键！适配辅助Agent） =====================
# 1. TASK_STATUSES：任务生命周期状态（映射原有TaskState枚举，适配任务调度Agent）
@unique
class TaskState(Enum):
    """任务状态枚举（适配任务调度Agent的TASK_STATUSES依赖）"""
    PENDING = "pending"    # 待执行（入队未处理）
    RUNNING = "running"    # 执行中（已出队执行）
    SUCCESS = "success"    # 成功（执行完成）
    FAILED = "failed"      # 失败（执行异常）
    RETRYING = "retrying"  # 重试中（失败后重试）
    REJECTED = "rejected"  # 拒绝（合规校验不通过）

# 导出为TASK_STATUSES，兼容任务调度Agent引用
TASK_STATUSES = TaskState

# 2. AGENT_STATUSES：Agent健康状态（映射原有AgentHealthStatus枚举，适配健康检查Agent）
@unique
class AgentHealthStatus(Enum):
    """Agent健康状态枚举（适配健康检查Agent的AGENT_STATUSES依赖）"""
    HEALTHY = "healthy"    # 健康：资源充足、无连续失败、心跳正常
    LOADING = "loading"    # 负载过高：CPU/内存/磁盘使用率超标
    UNHEALTHY = "unhealthy"# 不健康：心跳超时、连续失败≥3次
    UNKNOWN = "unknown"    # 未知：未获取到状态（补充，适配健康检查Agent）

# 导出为AGENT_STATUSES，兼容健康检查Agent引用
AGENT_STATUSES = AgentHealthStatus

# 3. AGENT_TYPES：系统支持的Agent类型列表（从AgentType枚举提取，适配健康检查Agent）
@unique
class AgentType(str, Enum):
    """Agent类型枚举（便于编排Agent调度）"""
    ORCHESTRATOR = "orchestrator"    # 编排Agent
    TEXT_QA = "text_qa"              # 文本问答Agent
    DOC_QA = "doc_qa"                # DocQA Agent
    MULTI_MODAL = "multi_modal"      # 多模态Agent
    TOOL_CALL = "tool_call"          # ToolCall Agent
    HEALTH_MONITOR = "health_monitor"# 健康监控Agent
    COMPLIANCE = "compliance"        # 合规Agent
    CONFIG_SYNC = "config_sync"      # 配置同步Agent

# 导出为AGENT_TYPES列表，适配健康检查Agent遍历需求
AGENT_TYPES: List[str] = [agent_type.value for agent_type in AgentType]

# 4. DEFAULT_RATE_LIMIT：默认限流配置（基于原有限流阈值，适配限流Agent）
DEFAULT_RATE_LIMIT: Dict[str, Dict[str, int]] = {
    "api": {
        "limit": RATE_LIMIT_GLOBAL,  # 接口级：复用全局限流1000次/分钟
        "period": 60  # 时间窗口（秒）
    },
    "agent": {
        "limit": AGENT_MAX_CONCURRENT,  # Agent级：复用单实例最大并发50次/分钟
        "period": 60
    },
    "user": {
        "limit": RATE_LIMIT_USER,  # 用户级：复用用户限流60次/分钟
        "period": 60
    }
}

# ===================== 模型管理相关常量 =====================
# 模型切换阈值（内存使用率%）
MODEL_SWITCH_THRESHOLD: Final[int] = 85
# 模型资源阈值配置
MODEL_RESOURCE_THRESHOLDS: Final[Dict[str, float]] = {
    "small": {"max_memory": 70.0, "min_memory": 0.0},     # 小型模型：内存使用率0-70%
    "medium": {"max_memory": 85.0, "min_memory": 30.0},  # 中型模型：内存使用率30-85%
    "large": {"max_memory": 100.0, "min_memory": 60.0}   # 大型模型：内存使用率60-100%
}
# 推荐模型配置
RECOMMENDED_MODELS: Final[Dict[str, Dict[str, str]]] = {
    "small": {"ollama": "phi3:3.8b-instruct-q4_K_M", "description": "小型量化模型，资源占用低"},
    "medium": {"ollama": "qwen2:7b-instruct-q4_K_M", "description": "中型量化模型，平衡性能和资源"},
    "large": {"ollama": "llama3", "description": "大型模型，性能最佳但资源占用高"}
}

# ===================== 原有业务枚举常量（保留不变，确保历史依赖正常） =====================
class AgentStatus(str, Enum):
    """Agent执行状态枚举（统一所有Agent的执行结果状态）"""
    SUCCESS = "success"  # 执行成功
    FAILED = "failed"    # 执行失败
    RUNNING = "running"  # 执行中
    PENDING = "pending"  # 等待执行

@unique
class TaskStatus(str, Enum):
    """任务整体状态枚举（区别于TaskState，描述任务整体进度）"""
    INIT = "init"                  # 初始化
    PROCESSING = "processing"      # 处理中
    COMPLETED = "completed"        # 全部完成
    PARTIAL_COMPLETED = "partial_completed"  # 部分完成（有Agent失败）
    FAILED = "failed"              # 任务失败（关键Agent失败）

@unique
class FallbackLevel(int, Enum):
    """回退策略级别"""
    LEVEL1 = 1  # 同集群备用实例
    LEVEL2 = 2  # 跨集群调度
    LEVEL3 = 3  # 缓存兜底
    LEVEL4 = 4  # 友好提示

# ===================== Redis集群模式配置 =====================
@unique
class RedisMode(str, Enum):
    """Redis部署模式枚举"""
    SINGLE = "single"      # 单节点模式
    SENTINEL = "sentinel"  # 哨兵模式
    CLUSTER = "cluster"    # 集群模式

# ===================== 错误码常量（统一API返回格式） =====================
class ErrorCode(int, Enum):
    """全局错误码"""
    SUCCESS = 0               # 成功
    SYSTEM_ERROR = -1         # 系统错误
    PARAM_ERROR = -2          # 参数错误
    REDIS_ERROR = -3          # Redis操作错误
    NACOS_ERROR = -4          # Nacos操作错误
    AGENT_CALL_ERROR = -5     # Agent调用错误
    LOCK_ACQUIRE_ERROR = -6   # 分布式锁获取失败
    RATE_LIMIT_ERROR = -7     # 限流触发
    COMPLIANCE_ERROR = -8     # 合规校验失败
    CIRCUIT_BREAKER_OPEN = -9 # 熔断器开启
    TOOL_ERROR = -10          # 工具操作错误
    MODEL_ERROR = -11         # 模型操作错误

# ===================== 消息队列频道名称（统一Pub/Sub频道） =====================
# TaskState状态更新频道（格式：task:state:update:{task_id}）
TASK_STATE_UPDATE_CHANNEL_PREFIX: Final[str] = "task:state:update:"
# Agent状态更新频道
AGENT_STATE_UPDATE_CHANNEL: Final[str] = "agent:state:update"
# 配置变更通知频道
CONFIG_UPDATE_CHANNEL: Final[str] = "config:update"
# 告警通知频道
ALERT_CHANNEL: Final[str] = "system:alert"